﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace TimerMod.Views
{
    /// <summary>
    /// Interaction logic for TimerWindow
    /// </summary>
    public partial class TimerWindow : UserControl
    {
        DispatcherTimer dispatcherTimer3;
        DispatcherTimer dispatcherTimer2;
        DispatcherTimer dispatcherTimer;
        public TimerWindow()
        {
            InitializeComponent();
            dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
            dispatcherTimer.Tick += DispatcherTimer_Tick;
            dispatcherTimer.Interval = TimeSpan.FromMilliseconds(50);
            //dispatcherTimer.Start();

            dispatcherTimer2 = new System.Windows.Threading.DispatcherTimer();
            dispatcherTimer2.Tick += DispatcherTimer2_Tick;
            dispatcherTimer2.Interval = TimeSpan.FromMilliseconds(50);

            dispatcherTimer3 = new System.Windows.Threading.DispatcherTimer();
            dispatcherTimer3.Tick += DispatcherTimer3_Tick;
            dispatcherTimer3.Interval = TimeSpan.FromMilliseconds(50);

            var minites = new List<int>();
            for (int i = 1; i <= 60; i++)
            {
                minites.Add(i);
            }
            cbMinite.ItemsSource = minites;
            //DrawScale();
            DrawS();
        }
        private void DispatcherTimer2_Tick(object sender, EventArgs e)
        {
            this.gaugeCanvas.Children.Clear();

            DrawScale();

            var currentTime = DateTime.Now;
            var spTime = currentTime - fTime;
            if (spTime.TotalSeconds <= fMiniter * 60)
            {
                var totalSecond = fMiniter * 60 - spTime.TotalSeconds;
                Draw2((int)totalSecond);
            }
            else
            {
                dispatcherTimer2.Stop();
            }
        }
        private void Draw2(int totalSecond)
        {
            int ds_m = totalSecond / 60;
            int ds_s = totalSecond % 60;
            double angel_s = ds_s * Math.PI / 30;
            double angel_m = ds_m * Math.PI / 30;
            Point o = new Point(230, 230);//圆心
            Point s = new Point((int)(230 + 150 * Math.Sin(angel_s)), (int)(230 - 150 * Math.Cos(angel_s)));
            Point m = new Point((int)(230 + 130 * Math.Sin(angel_m)), (int)(230 - 130 * Math.Cos(angel_m)));
            Line line_s = new Line();

            line_s.X1 = o.X;
            line_s.Y1 = o.Y;
            line_s.X2 = s.X;
            line_s.Y2 = s.Y;
            line_s.Stroke = Brushes.Red;
            line_s.StrokeThickness = 2;

            Line line_m = new Line();
            line_m.X1 = o.X;
            line_m.Y1 = o.Y;
            line_m.X2 = m.X;
            line_m.Y2 = m.Y;
            line_m.Stroke = Brushes.DarkGreen;
            line_m.StrokeThickness = 3;
            this.gaugeCanvas.Children.Add(line_s);
            this.gaugeCanvas.Children.Add(line_m);
        }
        private void DispatcherTimer_Tick(object sender, EventArgs e)
        {
            this.gaugeCanvas.Children.Clear();

            DrawScale();
            var ds = DateTime.Now;
            Clock(ds.Second, ds.Minute, ds.Hour);
        }
        private void DrawS()
        {
            //< Path Grid.Row = "1" Data = "M 430,230 A 200,200 0 1 1 430,229 Z" Stroke = "DarkRed" StrokeThickness = "30" Fill = "Transparent" />
            //System.Windows.Shapes.Ellipse ellipse = new System.Windows.Shapes.Ellipse(); ;
            //ellipse.Width = 200;
            //ellipse.Height = 200;
            //ellipse.Stroke = Brushes.Black;
            //ellipse.StrokeThickness = 2;
            //this.gaugeCanvas.Children.Add(ellipse);

            System.Windows.Shapes.Path myPath = new System.Windows.Shapes.Path();
            myPath.Stroke = Brushes.DarkGreen;
            myPath.StrokeThickness = 30;

            Draw1(myPath);

            System.Windows.Shapes.Path myPath2 = new System.Windows.Shapes.Path();
            myPath2.Stroke = Brushes.DarkGray;
            myPath2.StrokeThickness = 30;
            Draw11(myPath2);

            //myPath.Stroke = System.Windows.Media.Brushes.DarkGray;
            //myPath.Fill = System.Windows.Media.Brushes.Transparent;
            //myPath.StrokeThickness = 8;
            //myPath.HorizontalAlignment = HorizontalAlignment.Left;
            //myPath.VerticalAlignment = VerticalAlignment.Center;
            //EllipseGeometry myEllipseGeometry = new EllipseGeometry();
            //myEllipseGeometry.Center = new System.Windows.Point(230, 230);
            //myEllipseGeometry.RadiusX = 50;
            //myEllipseGeometry.RadiusY = 50;

            this.gaugeCanvas.Children.Add(myPath2);
            this.gaugeCanvas.Children.Add(myPath);

            //gaugeCanvas.HorizontalAlignment = HorizontalAlignment.Center;
            //gaugeCanvas.VerticalAlignment = VerticalAlignment.Center;
            //LineGeometry myLineGeometry = new LineGeometry();
        }
        /// <summary>
        /// 画表盘的刻度
        /// </summary>
        private void DrawScale()
        {
            for (int i = 0; i <= 360; i += 1)
            {
                //添加刻度线
                Line lineScale = new Line();

                lineScale.Stroke = new SolidColorBrush(Color.FromRgb(0xFF, 0x00, 0));//使用红色的线
                lineScale.StrokeThickness = 1;//线条的粗细为1
                                              //直线刻度的起点，注意角度转为弧度制
                                              //lineScale.X1 = 200 - 170 * Math.Cos(i * Math.PI / 180);
                                              //lineScale.Y1 = 200 - 170 * Math.Sin(i * Math.PI / 180);
                                              ////直线刻度的终点，注意角度转为弧度制
                                              //lineScale.X2 = 200 - 180 * Math.Cos(i * Math.PI / 180);
                                              //lineScale.Y2 = 200 - 180 * Math.Sin(i * Math.PI / 180);

                if (i % 30 == 0)
                {
                    lineScale.Stroke = new SolidColorBrush(Color.FromRgb(0x00, 0xFF, 0xFF));//使用红色的线
                    lineScale.StrokeThickness = 3;//线条的粗细为1
                    lineScale.X1 = 230 - 160 * Math.Cos(i * Math.PI / 180);
                    lineScale.Y1 = 230 - 160 * Math.Sin(i * Math.PI / 180);
                    //直线刻度的终点，注意角度转为弧度制
                    lineScale.X2 = 230 - 185 * Math.Cos(i * Math.PI / 180);
                    lineScale.Y2 = 230 - 185 * Math.Sin(i * Math.PI / 180);

                    //将直线画在Canvas画布上
                    this.gaugeCanvas.Children.Add(lineScale);
                }
                else if (i % 6 == 0)
                {
                    lineScale.Stroke = new SolidColorBrush(Color.FromRgb(0xFF, 0x00, 0));//使用红色的线
                    lineScale.StrokeThickness = 1;//线条的粗细为1
                    lineScale.X1 = 230 - 170 * Math.Cos(i * Math.PI / 180);
                    lineScale.Y1 = 230 - 170 * Math.Sin(i * Math.PI / 180);
                    //直线刻度的终点，注意角度转为弧度制
                    lineScale.X2 = 230 - 185 * Math.Cos(i * Math.PI / 180);
                    lineScale.Y2 = 230 - 185 * Math.Sin(i * Math.PI / 180);

                    //将直线画在Canvas画布上
                    this.gaugeCanvas.Children.Add(lineScale);
                }
                else
                {
                }
            }
        }
        public void Clock(int second, int minute, int hour)
        {
            Pen s_p = new Pen(Brushes.Yellow, 3);
            Pen m_p = new Pen(Brushes.Blue, 4);
            Pen h_p = new Pen(Brushes.Red, 5);

            double angel_s = second * Math.PI / 30;
            double angel_m = minute * Math.PI / 30;
            double angel_h = hour * Math.PI / 6 + minute * (1 / (Math.PI * 30));

            Point o = new Point(230, 230);//圆心
            Point s = new Point((int)(230 + 150 * Math.Sin(angel_s)), (int)(230 - 150 * Math.Cos(angel_s)));
            Point m = new Point((int)(230 + 130 * Math.Sin(angel_m)), (int)(230 - 130 * Math.Cos(angel_m)));
            Point h = new Point((int)(230 + 100 * Math.Sin(angel_h)), (int)(230 - 100 * Math.Cos(angel_h)));

            Line line_s = new Line();

            line_s.X1 = o.X;
            line_s.Y1 = o.Y;
            line_s.X2 = s.X;
            line_s.Y2 = s.Y;
            line_s.Stroke = Brushes.Red;
            line_s.StrokeThickness = 2;

            Line line_m = new Line();
            line_m.X1 = o.X;
            line_m.Y1 = o.Y;
            line_m.X2 = m.X;
            line_m.Y2 = m.Y;
            line_m.Stroke = Brushes.DarkGreen;
            line_m.StrokeThickness = 2;

            Line line_h = new Line();
            line_h.X1 = o.X;
            line_h.Y1 = o.Y;
            line_h.X2 = h.X;
            line_h.Y2 = h.Y;
            line_h.Stroke = Brushes.Black;
            line_h.StrokeThickness = 2;

            this.gaugeCanvas.Children.Add(line_h);

            this.gaugeCanvas.Children.Add(line_m);

            this.gaugeCanvas.Children.Add(line_s);
        }
        int fMiniter = 0;
        DateTime fTime;
        private void BtTimer_Click(object sender, RoutedEventArgs e)
        {
            fTime = DateTime.Now;

            dispatcherTimer?.Stop();
            if (cbMinite.SelectedItem != null)
            {
                var selectedMinite = cbMinite.SelectedItem.ToString();
                int.TryParse(selectedMinite, out fMiniter);

                dispatcherTimer2.Start();
            }
            else
            {
                fMiniter = 0;
            }
        }
        private void BtClock_Click(object sender, RoutedEventArgs e)
        {
            if (dispatcherTimer != null)
            {
                dispatcherTimer.Start();
            }
            else
            {
                dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
                dispatcherTimer.Tick += DispatcherTimer_Tick;
                dispatcherTimer.Interval = TimeSpan.FromMilliseconds(50);
                dispatcherTimer.Start();
            }
        }
        private void BtTimer2_Click(object sender, RoutedEventArgs e)
        {
            fTime = DateTime.Now;

            dispatcherTimer?.Stop();
            if (cbMinite.SelectedItem != null)
            {
                var selectedMinite = cbMinite.SelectedItem.ToString();
                int.TryParse(selectedMinite, out fMiniter);

                dispatcherTimer3.Start();
            }
            else
            {
                fMiniter = 0;
            }
        }
        #region 倒计时

        private void DispatcherTimer3_Tick(object sender, EventArgs e)
        {
            this.gaugeCanvas.Children.Clear();

            DrawScale2();

            var currentTime = DateTime.Now;
            var spTime = currentTime - fTime;
            if (spTime.TotalSeconds <= fMiniter * 60)
            {
                var totalSecond = fMiniter * 60 - spTime.TotalSeconds;
                var degree = totalSecond / (fMiniter * 60) * 360;
                Angle = degree;
                DrawS();

                var hour = totalSecond / (60 * 60);
                var minute = (totalSecond % (60 * 60)) / 60;
                var second = (totalSecond % (60 * 60)) % 60;
                var timeStr = $"{(int)hour:D2}:{(int)minute:D2}:{(int)second:D2}";

                DrawText(Diameter / 2 - 60, Diameter / 2, timeStr, Colors.Red, this.gaugeCanvas);
            }
            else
            {
                dispatcherTimer3.Stop();
            }
        }
        private double angle = 359.99;
        private int diameter = 200;
        /// <summary>
        /// 直径
        /// </summary>
        public int Diameter
        {
            get => diameter;
            set => diameter = value;
        }
        /// <summary>
        /// 角度
        /// </summary>
        public double Angle
        {
            get => angle;
            set => angle = value;
        }
        /// <summary>
        /// 表盘刻度线
        /// </summary>
        private void DrawScale2()
        {
            var radius = (Diameter - 30) / 2;
            for (int i = 0; i <= 360; i += 1)
            {
                //添加刻度线
                Line lineScale = new Line();

                lineScale.Stroke = new SolidColorBrush(Color.FromRgb(0xFF, 0x00, 0));//使用红色的线
                lineScale.StrokeThickness = 1;//线条的粗细为1
                                              //直线刻度的起点，注意角度转为弧度制
                                              //lineScale.X1 = 200 - 170 * Math.Cos(i * Math.PI / 180);
                                              //lineScale.Y1 = 200 - 170 * Math.Sin(i * Math.PI / 180);
                                              ////直线刻度的终点，注意角度转为弧度制
                                              //lineScale.X2 = 200 - 180 * Math.Cos(i * Math.PI / 180);
                                              //lineScale.Y2 = 200 - 180 * Math.Sin(i * Math.PI / 180);

                if (i % 30 == 0)
                {
                    lineScale.Stroke = new SolidColorBrush(Color.FromRgb(0x00, 0xFF, 0xFF));//使用红色的线
                    lineScale.StrokeThickness = 3;//线条的粗细为1
                    lineScale.X1 = radius - radius * Math.Cos(i * Math.PI / 180);
                    lineScale.Y1 = radius - radius * Math.Sin(i * Math.PI / 180);
                    //直线刻度的终点，注意角度转为弧度制
                    lineScale.X2 = radius - (radius - 30) * Math.Cos(i * Math.PI / 180);
                    lineScale.Y2 = radius - (radius - 30) * Math.Sin(i * Math.PI / 180);

                    //将直线画在Canvas画布上
                    this.gaugeCanvas.Children.Add(lineScale);
                }
                else if (i % 6 == 0)
                {
                    lineScale.Stroke = new SolidColorBrush(Color.FromRgb(0xFF, 0x00, 0));//使用红色的线
                    lineScale.StrokeThickness = 1;//线条的粗细为1
                    lineScale.X1 = radius - (radius + 0) * Math.Cos(i * Math.PI / 180);
                    lineScale.Y1 = radius - (radius + 0) * Math.Sin(i * Math.PI / 180);
                    //直线刻度的终点，注意角度转为弧度制
                    lineScale.X2 = radius - (radius - 20) * Math.Cos(i * Math.PI / 180);
                    lineScale.Y2 = radius - (radius - 20) * Math.Sin(i * Math.PI / 180);

                    //将直线画在Canvas画布上
                    this.gaugeCanvas.Children.Add(lineScale);
                }
                else
                {
                }
            }
        }
        private void Draw1(System.Windows.Shapes.Path path)
        {
            var degree = 180.00;
            // 0° 和 360° 是重合在一起的，ArcSegment 无法绘制重合的弧度。
            // 所以，最大角度是359。如果，目标值是 360° 则使用 PathFigure 中的属性 IsClose 闭合圆。
            var maxAngle = 359.99;
            // 获取最终角度
            var angle = Math.Min(maxAngle, Angle);
            // 绘制直径时，需要去掉边框尺寸，不然绘制的圆会超出正方形。
            var diameter = Diameter - path.StrokeThickness;
            // 根据数学公式计算出当前角度的弧度
            var arc = angle * Math.PI / degree;
            // 获取正弦值：a/c
            var sin = Math.Sin(arc);
            // 获取余弦值：b/c
            var cos = Math.Cos(arc);
            // 获取半径：c
            var radius = diameter / 2;
            // 获取 a
            var a = radius * sin;
            // 获取 b
            var b = radius * cos;
            // 获取终点位置：X
            var x = radius + a;
            // 获取终点位置：Y
            var y = radius - b;
            // 获取终点位置
            var endPoint = new Point(x, y);
            var segment = new ArcSegment();
            segment.IsLargeArc = angle > degree;
            segment.SweepDirection = SweepDirection.Clockwise;

            segment.Size = new Size(radius, radius);
            segment.Point = endPoint;

            var figure = new PathFigure();
            // 设置起点位置
            figure.StartPoint = new Point(radius, 0);
            figure.IsClosed = angle >= maxAngle;
            figure.Segments.Add(segment);

            var geometry = new PathGeometry();

            geometry.Figures.Add(figure);

            path.Data = geometry;
        }
        private void DrawText(double x, double y, string text, Color color, Canvas canvasObj)
        {
            TextBlock textBlock = new TextBlock();
            textBlock.Text = text;
            textBlock.FontSize = 20;
            textBlock.FontWeight = FontWeights.Bold;

            textBlock.Foreground = new SolidColorBrush(color);
            Canvas.SetLeft(textBlock, x);
            Canvas.SetTop(textBlock, y);
            canvasObj.Children.Add(textBlock);
        }
        private void Draw11(System.Windows.Shapes.Path path)
        {
            var degree = 180.00;
            // 0° 和 360° 是重合在一起的，ArcSegment 无法绘制重合的弧度。
            // 所以，最大角度是359。如果，目标值是 360° 则使用 PathFigure 中的属性 IsClose 闭合圆。
            var maxAngle = 359.99;
            // 获取最终角度
            var angle = Math.Min(maxAngle, maxAngle);
            // 绘制直径时，需要去掉边框尺寸，不然绘制的圆会超出正方形。
            var diameter = Diameter - path.StrokeThickness;
            // 根据数学公式计算出当前角度的弧度
            var arc = angle * Math.PI / degree;
            // 获取正弦值：a/c
            var sin = Math.Sin(arc);
            // 获取余弦值：b/c
            var cos = Math.Cos(arc);
            // 获取半径：c
            var radius = diameter / 2;
            // 获取 a
            var a = radius * sin;
            // 获取 b
            var b = radius * cos;
            // 获取终点位置：X
            var x = radius + a;
            // 获取终点位置：Y
            var y = radius - b;
            // 获取终点位置
            var endPoint = new Point(x, y);
            var segment = new ArcSegment();
            segment.IsLargeArc = angle > degree;
            segment.SweepDirection = SweepDirection.Clockwise;

            segment.Size = new Size(radius, radius);
            segment.Point = endPoint;

            var figure = new PathFigure();
            // 设置起点位置
            figure.StartPoint = new Point(radius, 0);
            figure.IsClosed = angle >= maxAngle;
            figure.Segments.Add(segment);
            var geometry = new PathGeometry();

            geometry.Figures.Add(figure);

            path.Data = geometry;
        }
        #endregion 倒计时
    }
}